package com.bbzn.device.client.service.emq.alarm;

import com.alibaba.fastjson.JSONObject;
import com.bbzn.device.client.config.EmqCode;
import com.bbzn.device.client.config.EmqxMqttProperties;
import com.bbzn.device.client.config.Oauth2Constant;
import com.bbzn.device.client.dao.mqttsub.EmqApiPublishEntity;
import com.bbzn.device.client.dataobject.*;
import com.bbzn.device.client.dto.ct.data.EmqAlarmDTO;
import com.bbzn.device.client.dto.device.DeviceDTO;
import com.bbzn.device.client.service.*;
import com.bbzn.device.client.utils.*;
import com.bbzn.device.client.utils.app.push.UmengUtil;
import com.bbzn.user.client.UserClient;
import com.bbzn.user.comment.User;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.Resource;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author wulongbo
 * @Date 2021/12/2 8:53
 * @Version 1.0
 */

@Slf4j
public class EmqBaseAlarm {

    @Resource
    private DeviceService deviceService;

    @Resource
    private UserClient userClient;

    @Resource
    private AlarmHisService alarmHisService;

    @Resource
    private AlarmHisEnService alarmHisEnService;

    @Resource
    private AlarmCnEnService alarmCnEnService;

    @Autowired
    private DeviceShareService deviceShareService;

    @Resource
    private EmqxMqttProperties emqxMqttProperties;

    @Autowired
    private EmqApiService emqApiService;

    @Resource
    private ToEmailService toEmailService;

    @Autowired
    private RedisUtils redisUtil;

    public void alarmRun(EmqAlarmDTO emqAlarmDTO) {
        Device device = new Device();
        device.setImei(emqAlarmDTO.getImei());
        List<Device> deviceList = deviceService.findByAll(device);
        if (CollectionUtils.isEmpty(deviceList)) {
            return;
        }
        device = deviceList.get(0);
        Long userId = device.getUserId();
        if (userId == null) {
            return;
        }
        log.info("设备绑定的用户id:" + userId);
        User user = null;
        try {
            user = userClient.selectByPrimaryKey(userId);
        } catch (Exception e) {
            e.printStackTrace();
        }

        String operator = user.getUsername();
        if (StringUtils.isEmpty(operator)) {
            operator = user.getPhone();
        }

        // 记录xxx报警历史（中文）
        AlarmHis alarmHis = new AlarmHis();
        alarmHis.setImei(emqAlarmDTO.getImei());
        // 报警类型（1：设备上线 /  2：设备离线 / 3：围栏正常 / 4：围栏异常/ 5：手环脱落 / 6：手表佩戴 / 7：血压预警  / 8：心率预警 / 9：温度预警 /10：烟雾报警 /11：低电压报警/12：烟雾感应报警 /13：血氧预警）
        alarmHis.setAlarmType(emqAlarmDTO.getAlarmType());
        alarmHis.setCreateTime(new Timestamp(System.currentTimeMillis()));
        alarmHis.setTitle(emqAlarmDTO.getTitle());
        alarmHis.setSigh(emqAlarmDTO.getCnSign());
        alarmHis.setCreatedBy(operator);
        alarmHis.setUserId(userId);
        alarmHis.setUserName(operator);
        alarmHis.setDeviceCategoryId(device.getDeviceCategoryId());
        alarmHis.setLat(emqAlarmDTO.getLat());
        alarmHis.setLon(emqAlarmDTO.getLon());
        alarmHis.setLocation(emqAlarmDTO.getLocation());
        alarmHis.setType(emqAlarmDTO.getType());
        alarmHis.setHeadImg(user.getImgUrl());
        alarmHisService.insertSelective(alarmHis);

        // 记录xxx报警历史（EN）
        AlarmHisEn alarmHisEn = new AlarmHisEn();
        alarmHisEn.setImei(emqAlarmDTO.getImei());
        // 报警类型（1：设备上线 /  2：设备离线 / 3：围栏正常 / 4：围栏异常/ 5：手环脱落 / 6：手表佩戴 / 7：血压预警  / 8：心率预警 / 9：温度预警 /10：烟雾报警 /11：低电压报警/12：烟雾感应报警 /13：血氧预警）
        alarmHis.setAlarmType(emqAlarmDTO.getAlarmType());
        alarmHisEn.setCreateTime(new Timestamp(System.currentTimeMillis()));
        alarmHisEn.setTitle(emqAlarmDTO.getEnTitle());
        alarmHisEn.setSigh(emqAlarmDTO.getEnSign());
        alarmHisEn.setCreatedBy(operator);
        alarmHisEn.setUserId(userId);
        alarmHisEn.setUserName(operator);
        alarmHisEn.setDeviceCategoryId(device.getDeviceCategoryId());
        alarmHisEn.setLat(emqAlarmDTO.getLat());
        alarmHisEn.setLon(emqAlarmDTO.getLon());
        alarmHisEn.setLocation(emqAlarmDTO.getLocation());
        alarmHisEn.setType(emqAlarmDTO.getType());
        alarmHisEn.setHeadImg(user.getImgUrl());
        alarmHisEnService.insertSelective(alarmHisEn);

        // 记录关联关系
        AlarmCnEn alarmCnEn = new AlarmCnEn();
        alarmCnEn.setCnId(alarmHis.getId());
        alarmCnEn.setEnId(alarmHisEn.getId());
        alarmCnEn.setCreateTime(new Timestamp(System.currentTimeMillis()));
        alarmCnEn.setCreatedBy(operator);
        alarmCnEnService.insertSelective(alarmCnEn);


        List<Long> receiveIds = deviceShareService.findReceiveIdByImei(emqAlarmDTO.getImei());
        List<String> appPushList = new ArrayList<>();

        if (CollectionUtils.isNotEmpty(receiveIds)) {
            receiveIds.stream().forEach(
                    receiveId -> {
                        String result = redisUtil.get(String.valueOf(receiveId));
                        if (StringUtils.isNotEmpty(result)) {
                            appPushList.add(result);
                        }
                    }
            );
        }
        String value = redisUtil.get(String.valueOf(userId));
        if (StringUtils.isNotEmpty(value)) {
            appPushList.add(value);
            log.info("登录的友盟数据value:" + value);
        }

        // 推送APP
        if (CollectionUtils.isNotEmpty(appPushList)) {
            appPushList.stream().forEach(
                    push -> {
                        JSONObject jsonObject = JSONObject.parseObject(push);
                        Integer type = jsonObject.getInteger("type");
                        String pushToken = jsonObject.getString("pushToken");
                        if (OptionalBean.ofNullable(pushToken).isPresent()) {
                            if (type.compareTo(1) == 0) {
                                try {
                                    UmengUtil.sendAndroidBroadcast(pushToken, emqAlarmDTO.getCnSign(), alarmHis.getTitle());
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            }
                            if (type.compareTo(2) == 0) {
                                try {
                                    UmengUtil.sendIOSUnicast(pushToken, emqAlarmDTO.getCnSign());
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            }
                        }
                    });
        }

        // web端xxx开关检查
        List<Boolean> booleanList = emqAlarmDTO.getBooleanList();
        if (booleanList.get(0)) {
            DeviceDTO deviceDTO = new DeviceDTO();
            deviceDTO.setImei(emqAlarmDTO.getImei());
            List<Long> pushIds = deviceService.getOperatorIdsBySelective(deviceDTO);
            // 异常消息统一推送给web前端
            // 组装json
            JSONObject data = new JSONObject();
            data.put("CN", emqAlarmDTO.getCnSign());
            data.put("EN", emqAlarmDTO.getEnSign());
            data.put("cid", alarmHis.getId());
            data.put("eid", alarmHisEn.getId());
            data.put("type", emqAlarmDTO.getAlarmType());
            data.put("lat", emqAlarmDTO.getLat());
            data.put("lon", emqAlarmDTO.getLon());
            data.put("location", emqAlarmDTO.getLocation());
            data.put("name", operator);
            data.put("imei", emqAlarmDTO.getImei());
            data.put("headImg", user.getImgUrl());
            data.put("time", System.currentTimeMillis());

            String payload = data.toJSONString();

            // EMQ 指定客户端主题批量订阅 topic
            String url = emqxMqttProperties.getHostUrl();
            String postUri = Oauth2Constant.EMQ_API_HTTP
                    + url.substring(0, url.lastIndexOf(":")).substring(url.indexOf(":")) + Oauth2Constant.EMQ_API_PUBLISHBATCH_ADR;

            List<EmqApiPublishEntity> mq = pushIds.stream().map(id -> {
                EmqApiPublishEntity entity = new EmqApiPublishEntity();
                entity.setQos(2);
                entity.setTopics(EmqCode.webTopic + id + EmqCode.endTopic);
                entity.setPayload(payload);
                return entity;
            }).collect(Collectors.toList());
            emqApiService.publishBatch(postUri, mq);
//            publishService.sendToMqtt(data.toJSONString(), EmqCode.webTopic + userId + EmqCode.endTopic);

        }
        if (booleanList.get(1) && StringUtils.isNotEmpty(user.getEmail())) {
            // 发送邮件
            ToEmail toEmail = new ToEmail();
            toEmail.setSubject("【把把智能科技】"); // 邮件主题
            toEmail.setContent(emqAlarmDTO.getCnSign()); // 邮件内容
            toEmail.setTos(new String[]{user.getEmail()}); // 邮件接收方，可多人
            toEmailService.commonEmail(toEmail);
        }

        // {1}消息： 人员：{2}已{3}了{4}，为保障设备安全，请勿向他人泄露此消息。
        if (booleanList.get(2) && StringUtils.isNotEmpty(user.getPhone())) {
            // 发送短信
            try {
                String[] params = new String[]{operator, emqAlarmDTO.getImei(), emqAlarmDTO.getCnSign()};
                VerPhoneCodeUtils.emqWebHookSendMessage("86", new String[]{user.getPhone()}, 1225361, params);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return;
    }

    protected Long checkPayload(List<String> list, String payload) {
        boolean check = ParamCheckUtils.checkJson(list, payload);
        if (!check) {
            return null;
        }
        JSONObject jsonObject = JSONObject.parseObject(payload);
        String imei = jsonObject.getString("imei");
        Device device = new Device();
        device.setImei(imei);
        List<Device> deviceList = deviceService.findByAll(device);
        if (CollectionUtils.isEmpty(deviceList)) {
            return null;
        }
        device = deviceList.get(0);
        return device.getUserId();
    }
}
